package com.lz.concurrent.thread;

import java.util.concurrent.TimeUnit;

/**
 * InterruptDemo..
 *
 * @see <a href="https://www.cnblogs.com/dz11/p/10162616.html">处理InterruptedException</a>
 *
 * @author Lizhong
 * @date 2019/3/13
 */

public class InterruptDemo {

    public static void main(String[] args) throws InterruptedException {
        Thread thread01 = new Thread(InterruptDemo::runnable);
        thread01.start();
        Thread thread02 = new Thread(InterruptDemo::runnable02);
        thread02.start();


        TimeUnit.SECONDS.sleep(1);
        thread01.interrupt();
        thread02.interrupt();

        thread02.join();
        thread01.join();
        System.err.println("-----所有线程结束----");
        boolean alive = thread01.isAlive();
        boolean interrupted = thread01.isInterrupted();
        System.out.printf("[%s]:[alive]:%s;[interrupted]:%s\n", thread02.getId(), alive, interrupted);
        boolean alive02 = thread02.isAlive();
        boolean interrupted02 = thread01.isInterrupted();
        System.out.printf("[%s]:[alive]:%s;[interrupted]:%s\n", thread02.getId(), alive02, interrupted02);
    }

    /**
     * 线程中断信号，interrupt，配合join wait sleep Block将会抛出interrupt异常，然后线程停止，
     * 清除interrupt标志 如果没有阻塞仅仅是信号的改变
     */
    private static void runnable() {
        ProcessHandle current = ProcessHandle.current();
        long pid = current.pid();
        Thread thread = Thread.currentThread();
        pid = thread.getId();
        for (; ; ) {
            boolean alive = thread.isAlive();
            // 手动中断
            boolean interrupted = thread.isInterrupted();
            System.out.printf("[%s]:[alive]:%s;[interrupted]:%s\n", pid, alive, interrupted);

            // 当有中断退出
            if (interrupted) {
                break;
            }
        }
    }

    private static void runnable02() {
        ProcessHandle current = ProcessHandle.current();
        long pid = current.pid();
        Thread thread = Thread.currentThread();
        pid = thread.getId();

        for (int i=0; ;i++ ) {
            boolean alive = thread.isAlive();
            // 判断中断位子
            boolean interrupted = thread.isInterrupted();
            System.out.printf("[%s]:[alive]:%s;[interrupted]:%s\n", pid, alive, interrupted);

            try {
                TimeUnit.SECONDS.sleep(3);
                // 抛出中断异常后 中断标志位 清除 interrupted==false
            } catch (InterruptedException e) {
                System.err.printf("[%s]:[alive]:%s;[interrupted]:%s\n", pid, alive, interrupted);
                // 第二种，异常清除后，到再次中断
                thread.interrupt();
            }

            // 当有中断退出，因此中断位被清除永远不会执行
            // 第二种,添加一行代码后中断会退出
            if (interrupted ) {
                break;
            }

            // 超时自动退出
            if(i==10) break;
        }
    }
}
